package dyyx.demo;

import java.time.Duration;
import java.util.Arrays;
import java.util.List;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public class ReactorDemo {

	private static List<String> words = Arrays.asList("the", "quick", "brown", "fox", "jumped", "over", "the", "lazy",
			"dog");

	public static void main(String[] args) throws Exception {
		
		// https://www.infoq.com/articles/reactor-by-example/

		// public abstract class Flux<T> implements Publisher<T>
		Flux<String> fewWords = Flux.just("Hello", "World");
		Flux<String> manyWords = Flux.fromIterable(words);

		// public final Disposable subscribe(Consumer<? super T> consumer)
		fewWords.subscribe(System.out::println);
		System.out.println();
		manyWords.subscribe(System.out::println);
		
		System.out.println("findingMissingLetter \n\n ");
		findingMissingLetter();
		System.out.println("\n\n");
		
		System.out.println("restoringMissingLetter s \n\n ");
		restoringMissingLetter();
		System.out.println("\n\n");

		
		blocks();
		
		// shortCircuit();
		

	}
	
	private static void findingMissingLetter() {
		Flux<String> manyLetters = Flux.fromIterable(words).flatMap(word -> Flux.fromArray(word.split(""))).distinct()
				.sort()
				.zipWith(Flux.range(1, Integer.MAX_VALUE), (string, count) -> String.format("%2d. %s", count, string));

		manyLetters.subscribe(System.out::println);
	}
	
	private static  void restoringMissingLetter() {
		  Mono<String> missing = Mono.just("s");
		  Flux<String> allLetters = Flux
		        .fromIterable(words)
		        .flatMap(word -> Flux.fromArray(word.split("")))
		        .concatWith(missing)
		        .distinct()
		        .sort()
		        .zipWith(Flux.range(1, Integer.MAX_VALUE),
		              (string, count) -> String.format("%2d. %s", count, string));

		  allLetters.subscribe(System.out::println);
		}
	
	
	private static void shortCircuit() {
		  Flux<String> helloPauseWorld = 
		              Mono.just("Hello")
		                  .concatWith(Mono.just("world"))
		                  // .delaySubscriptionMillis(500));
		                  .delaySubscription(Duration.ofMillis(500));
		                		  
		  helloPauseWorld.subscribe(System.out::println);
		}
	
	private static void blocks() {
		  Flux<String> helloPauseWorld = 
		    Mono.just("Hello")
		        .concatWith(Mono.just("world")
		                        .delaySubscription(Duration.ofMillis(500)));

		  helloPauseWorld.toStream()
		                 .forEach(System.out::println);
		}
	
	
}
